package com.nvn.washiodriver.activities;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.nvn.washiodriver.R;
import com.nvn.washiodriver.Objects.Order;
import com.nvn.washiodriver.Objects.OrderStatus;
import com.nvn.washiodriver.network.NetworkUtils;
import com.nvn.washiodriver.network.WebServiceCommunicatorListener;
import com.nvn.washiodriver.network.ws.BaseWSControl;
import com.nvn.washiodriver.network.ws.BaseWSControl.WebServiceFlag;
import com.nvn.washiodriver.network.ws.UpdateOrderStatusWSControl;
import com.nvn.washiodriver.utils.SessionManager;
import com.nvn.washiodriver.utils.Statics;
import com.nvn.washiodriver.views.CustomDialog;

public class OrderDetailActivity extends BaseActivity implements
		OnClickListener, WebServiceCommunicatorListener {
	public static int RQ_NOTE = 123;
	public static int RQ_BAGS = 124;
	private Order mOrder;
	private ProgressDialog pd;
	private CustomDialog mDialogStatuses;
	private int mPosStatus;
	private TextView mTvCustomer, mTvAddress, mTvPhone, mTvEsTime,
			mTvOrderStatus, mTvDriverNote, mTvAdressNote, mTvCusNote,
			mTvAdminNote, mTvDistance, mTvType, mTvEditNote, mTvNumBags,
			mTvVip, mTvNew, mTvZip;
	private Button mBtnCotact, mBtnDirection, mBtnBags;
	private View groupAddrNote, groupCusNote, groupAdminNote;
	private GoogleMap mMap;
	private ArrayList<Object> arr;
	private Polyline mMutablePolyline;
	private ScrollView mRootView;
	private GetDirection mTaskGetDirection;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_order_detail);
		initView();
		initProperties();
		setUpMapIfNeeded();
		initListeners();
	}

	@Override
	protected void initView() {
		super.initView();
		mRootView = (ScrollView) findViewById(R.id.root_view);

		mTvCustomer = (TextView) findViewById(R.id.tv_customer);
		mTvAddress = (TextView) findViewById(R.id.tv_address);
		mTvPhone = (TextView) findViewById(R.id.tv_phone);
		mTvEsTime = (TextView) findViewById(R.id.tv_time_eta);
		mTvDistance = (TextView) findViewById(R.id.tv_distance);
		mTvType = (TextView) findViewById(R.id.tv_type);
		mTvEditNote = (TextView) findViewById(R.id.tv_editnote);
		mTvNumBags = (TextView) findViewById(R.id.tv_num_bags);
		mTvVip = (TextView) findViewById(R.id.tv_vip);
		mTvNew = (TextView) findViewById(R.id.tv_new);
		mTvZip = (TextView) findViewById(R.id.tv_zipcode);

		mTvDriverNote = (TextView) findViewById(R.id.tv_driver_note);
		mTvAdressNote = (TextView) findViewById(R.id.tv_address_note);
		mTvCusNote = (TextView) findViewById(R.id.tv_customer_note);
		mTvAdminNote = (TextView) findViewById(R.id.tv_admin_note);
		
		groupAddrNote = findViewById(R.id.group_address_note);
		groupAdminNote = findViewById(R.id.group_admin_note);
		groupCusNote = findViewById(R.id.group_customer_note);

		mBtnBags = (Button) findViewById(R.id.btn_bag);
		mBtnCotact = (Button) findViewById(R.id.btn_contact);
		mBtnDirection = (Button) findViewById(R.id.btn_direction);

		mTvOrderStatus = (TextView) findViewById(R.id.tv_order_status);

	}

	@Override
	protected void onResume() {
		super.onResume();
		setUpMapIfNeeded();
	}

	private void initProperties() {
		mImvTitle.setImageResource(R.drawable.button_back);

		mOrder = SessionManager.getSessionManager(this).getCurOrder();
		if (mOrder == null) {
			Statics.showToast(this, "This order is not exist!");
			finish();
		}

		fillData();

		arr = new ArrayList<Object>();
		ArrayList<OrderStatus> statuses = SessionManager
				.getSessionManager(this).getoStatuses();

		if (mOrder.isPickUp()) {
			for (int i = 0; i < statuses.size(); i++) {
				OrderStatus status = statuses.get(i);

				if (status.isPickUp()) {
					arr.add(status);

					if (status.getsLookup().equals(
							mOrder.getoStatus().getsLookup())) {
						mPosStatus = arr.size() - 1;
					}
				}
			}
		} else if (mOrder.isDropOff()) {
			for (int i = 0; i < statuses.size(); i++) {
				OrderStatus status = statuses.get(i);

				if (status.isDropOff()) {
					arr.add(status);

					if (status.getsLookup().equals(
							mOrder.getoStatus().getsLookup())) {
						mPosStatus = arr.size() - 1;
					}
				}
			}
		}

		pd = new ProgressDialog(this);
		pd.setCancelable(false);
		pd.setMessage("Loading...");
	}

	private void fillData() {
		mTvCustomer.setText(mOrder.getCustomer());
		mTvType.setText(mOrder.getServiceType());

		if (getIntent().getBooleanExtra("FIRST_ORDER", false)) {
			mTvNew.setBackgroundResource(R.drawable.btn_blue_5dp);
		} else {
			mTvNew.setBackgroundResource(R.drawable.btn_gray_5dp);
		}
		
		if (mOrder.isVip()) {
			mTvVip.setBackgroundResource(R.drawable.btn_blue_5dp);
		} else {
			mTvVip.setBackgroundResource(R.drawable.btn_gray_5dp);
		}

		mTvTitle.setText(mOrder.getTime());

		if (mOrder.getEsTime().equals("ETA_min")) {
			mTvEsTime.setText("ETA_min");
		} else {
			mTvEsTime.setText("ETA: " + mOrder.getEsTime());
		}
		mTvDistance.setText(mOrder.getEsDistance());

		if (mOrder.getAddress().length() > 0) {
			mTvAddress.setText(mOrder.getAddress());
		} else {
			mTvAddress.setVisibility(View.INVISIBLE);
		}

		if (mOrder.getPhone().length() > 0) {
			mTvPhone.setText("#" + mOrder.getPhone());
		} else {
			mTvPhone.setVisibility(View.INVISIBLE);
		}

		if (mOrder.getZip().length() > 0) {
			mTvZip.setText(mOrder.getZip());
		} else {
			mTvZip.setVisibility(View.INVISIBLE);
		}

		mTvOrderStatus.setText(mOrder.getoStatus().toString());

		int numBags = mOrder.getDryCleanCout() + mOrder.getLaundryCount();
		if (numBags > 0) {
			mTvNumBags.setText(numBags + "");
		} else {
			mTvNumBags.setVisibility(View.INVISIBLE);
		}


		if (mOrder.getDriverNote().length() > 0) {
			mTvDriverNote.setVisibility(View.VISIBLE);
			mTvDriverNote.setText(mOrder.getDriverNote());
		}

		if (mOrder.getAdressNote().length() > 0) {
			groupAddrNote.setVisibility(View.VISIBLE);
			mTvAdressNote.setText(mOrder.getAdressNote());
		}

		if (mOrder.getCusNote().length() > 0) {
			groupCusNote.setVisibility(View.VISIBLE);
			mTvCusNote.setText(mOrder.getCusNote());
		}

		if (mOrder.getAdminNote().length() > 0) {
			groupAdminNote.setVisibility(View.VISIBLE);
			mTvAdminNote.setText(mOrder.getAdminNote());
		}
	}

	private void initListeners() {
		mBtnDirection.setOnClickListener(this);
		mBtnCotact.setOnClickListener(this);
		mBtnBags.setOnClickListener(this);

		mTvEditNote.setOnClickListener(this);

		mTvOrderStatus.setOnClickListener(this);
		findViewById(R.id.transparent_layout).setOnTouchListener(
				new View.OnTouchListener() {

					@Override
					public boolean onTouch(View v, MotionEvent event) {
						int action = event.getAction();
						switch (action) {
						case MotionEvent.ACTION_DOWN:
							// Disallow ScrollView to intercept touch events.
							mRootView.requestDisallowInterceptTouchEvent(true);
							// Disable touch on transparent view
							return false;

						case MotionEvent.ACTION_UP:
							// Allow ScrollView to intercept touch events.
							mRootView.requestDisallowInterceptTouchEvent(false);
							return true;

						case MotionEvent.ACTION_MOVE:
							mRootView.requestDisallowInterceptTouchEvent(true);
							return false;

						default:
							return true;
						}
					}
				});
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		// case R.id.btn_call:
		// Intent iCall = new Intent(Intent.ACTION_CALL);
		// iCall.setData(Uri.parse("tel:" + Statics.WASHIO_PHONE));
		// startActivity(iCall);
		// break;
		//
		// case R.id.btn_sms:
		// Intent iSms = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:"
		// + Statics.WASHIO_PHONE));
		// startActivity(iSms);
		// break;

		case R.id.tv_order_status:
			showDialogStatuses();
			break;

		case R.id.btn_direction:
			if (Statics.curLat != 0) {
				Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
						Uri.parse("http://maps.google.com/maps?saddr="
								+ Statics.curLat + "," + Statics.curLon
								+ "&daddr=" + mOrder.getLatitude() + ","
								+ mOrder.getLongitude()));
				PackageManager pm = getPackageManager();
				List<ResolveInfo> resInfo = pm.queryIntentActivities(intent, 0);
				boolean isStart = false;
				for (int i = 0; i < resInfo.size(); i++) {
					// Extract the label, append it, and repackage it in a
					// LabeledIntent
					ResolveInfo ri = resInfo.get(i);
					String packageName = ri.activityInfo.packageName;
					if (packageName.contains("com.google.android.apps.map")) {
						intent.setClassName(packageName, ri.activityInfo.name);
						startActivity(intent);
						isStart = true;
					}
				}
				if (!isStart) {
					// show dialog
					new AlertDialog.Builder(OrderDetailActivity.this)
							.setTitle("Notice")
							.setMessage(
									"Oops! Missing Map Application.\nDownload it now?")
							.setPositiveButton("Ok",
									new DialogInterface.OnClickListener() {

										@Override
										public void onClick(
												DialogInterface dialog,
												int which) {
											Intent goToMarket = new Intent(
													Intent.ACTION_VIEW,
													Uri.parse("market://details?id=com.google.android.apps.maps"));
											startActivity(goToMarket);
										}
									})
							.setNegativeButton("Cancel",
									new DialogInterface.OnClickListener() {

										@Override
										public void onClick(
												DialogInterface arg0, int arg1) {
										}
									}).show();
				}

			} else {
				Statics.showToast(this, "Waiting for your location");
			}
			break;
		case R.id.btn_contact:
			if (mOrder.getPhone() != null && mOrder.getPhone().length() > 0) {
				List<Object> action = new ArrayList<Object>();
				action.add("Send An SMS");
				action.add("Make A Call");
				CustomDialog dialog = new CustomDialog(this, action,
						mOrder.getPhone(), -1);
				dialog.setOnClickItem(new CustomDialog.OnClickItem() {

					@Override
					public void Click(int position) {
						switch (position) {
						case 1:
							startActivity(new Intent(Intent.ACTION_SENDTO, Uri
									.parse("smsto:" + mOrder.getPhone())));
							break;
						case 2:

							startActivity(new Intent(Intent.ACTION_CALL, Uri
									.parse("tel:" + mOrder.getPhone())));
							break;
						default:
							break;
						}
					}
				});
				dialog.show();
			}
			break;
		case R.id.tv_editnote:
			Intent i = new Intent(this, NoteActivity.class);
			i.putExtra("TITLE", "Note");
			startActivityForResult(i, RQ_NOTE);
			break;
		case R.id.btn_bag:
			Intent intent = new Intent(this, BagsActivity.class);
			intent.putExtra("TITLE", "Bags");
			startActivityForResult(intent, RQ_BAGS);
			break;

		// case R.id.btn_show_map:
		// String lat = mOrder.getLatitude();
		// String lon = mOrder.getLongitude();
		// String label = mOrder.getAddress();
		// String uriString = "http://maps.google.com/maps?q=" + lat + ','
		// + lon + "(" + label + ")&z=15";
		//
		// Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uriString));
		// PackageManager pm = getPackageManager();
		// try {
		// pm.getApplicationInfo("com.google.android.apps.map",
		// PackageManager.GET_META_DATA);
		// intent.setClassName("com.google.android.apps.maps",
		// "com.google.android.apps.gmm.base.app.GoogleMapsApplication");
		// startActivity(intent);
		// } catch (Exception e) {
		// // show dialog
		// new AlertDialog.Builder(OrderDetailActivity.this)
		// .setTitle("Notice")
		// .setMessage(
		// "Oops! Missing Map Application.\nDownload it now?")
		// .setPositiveButton("Ok",
		// new DialogInterface.OnClickListener() {
		//
		// @Override
		// public void onClick(DialogInterface dialog,
		// int which) {
		// Intent goToMarket = new Intent(
		// Intent.ACTION_VIEW,
		// Uri.parse("market://details?id=com.google.android.apps.maps"));
		// startActivity(goToMarket);
		// }
		// })
		// .setNegativeButton("Cancel",
		// new DialogInterface.OnClickListener() {
		//
		// @Override
		// public void onClick(DialogInterface arg0,
		// int arg1) {
		// }
		// }).show();
		// }
		//
		// break;
		}

	}

	@Override
	public void onConnectionOpen(BaseWSControl wsControl, WebServiceFlag flag) {
		pd.setMessage("Loading...");
		pd.show();
	}

	@Override
	public void onConnectionError(BaseWSControl wsControl, WebServiceFlag flag,
			String error) {
		Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
		pd.dismiss();
	}

	@Override
	public void onConnectionDone(BaseWSControl wsControl, WebServiceFlag flag,
			Object result) {
		if (flag == WebServiceFlag.UPDATE_ORDER_STATUS) {
			setResult(RESULT_OK);
		}
		pd.dismiss();
	}

	@Override
	public void onUpdateData(BaseWSControl wsControl, WebServiceFlag flag,
			Object data) {
	}

	public void showDialogStatuses() {

		mDialogStatuses = new CustomDialog(this, arr, getResources().getString(
				R.string.txt_map_type), mPosStatus);
		mDialogStatuses.setOnClickItem(new CustomDialog.OnClickItem() {

			@Override
			public void Click(int position) {
				position -= 1;
				mTvOrderStatus.setText(arr.get(position).toString());
				mPosStatus = position;

				new UpdateOrderStatusWSControl(OrderDetailActivity.this,
						OrderDetailActivity.this, mOrder.getObjectId(),
						((OrderStatus) arr.get(position)).getObjectId())
						.execute();
			}
		});
		mDialogStatuses.show();
	}

	@Override
	protected void onDestroy() {
		if (mTaskGetDirection != null) {
			mTaskGetDirection.cancel(true);
			mTaskGetDirection = null;
		}
		super.onDestroy();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (resultCode == RESULT_OK) {
			if (requestCode == RQ_NOTE) {
				String notes = data.getStringExtra("NOTE").trim();
				mOrder.setDriverNote(notes);
				if (notes.length() > 0) {
					mTvDriverNote.setVisibility(View.VISIBLE);
					mTvDriverNote.setText(notes);
				}else{
					mTvDriverNote.setVisibility(View.GONE);
				}
			} else if (requestCode == RQ_BAGS) {
				int laundryCount = data.getIntExtra("LAUNDRY", 0);
				int drycleanCount = data.getIntExtra("DRYCLEAN", 0);
				mOrder.setLaundryCount(laundryCount);
				mOrder.setDryCleanCout(drycleanCount);
				
				int numBags = laundryCount + drycleanCount;
				if (numBags > 0) {
					mTvNumBags.setVisibility(View.VISIBLE);
					mTvNumBags.setText(numBags + "");
				} else {
					mTvNumBags.setVisibility(View.INVISIBLE);
				}
			}
			setResult(RESULT_OK);
		}
	}

	private void setUpMapIfNeeded() {
		// Do a null check to confirm that we have not already instantiated the
		// map.
		if (mMap == null) {
			SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
					.findFragmentById(R.id.map);
			// Try to obtain the map from the SupportMapFragment.
			mMap = mapFragment.getMap();
			// Check if we were successful in obtaining the map.
			if (mMap != null) {
				setUpMap();
			}
		}
	}

	/**
	 * This is where we can add markers or lines, add listeners or move the
	 * camera. In this case, we just add a marker near Africa.
	 * <p>
	 * This should only be called once and when we are sure that {@link #mMap}
	 * is not null.
	 */
	private void setUpMap() {
		mMap.clear();
		if (mOrder != null) {
			final LatLng orderPosition = new LatLng(Double.parseDouble(mOrder
					.getLatitude()), Double.parseDouble(mOrder.getLongitude()));
			mMap.animateCamera(CameraUpdateFactory
					.newCameraPosition(new CameraPosition(orderPosition, 14, 0,
							0)));
			mMap.addMarker(
					new MarkerOptions().position(orderPosition).icon(
							BitmapDescriptorFactory
									.fromResource(R.drawable.pinner)))
					.setTitle(mOrder.getAddress());
			// final LatLng currentPosition = new LatLng(Statics.curLat,
			// Statics.curLon);
			// // final LatLng currentPosition = new LatLng(42.979215,
			// // -102.356755);
			// mMap.addMarker(new MarkerOptions().position(orderPosition));
			//
			// mMap.addMarker(new MarkerOptions().position(currentPosition));
			//
			// LatLngBounds bounds = new LatLngBounds.Builder()
			// .include(orderPosition).include(currentPosition).build();
			// try {
			// mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
			// 50));
			// } catch (Exception e) {
			// final View mapView = getSupportFragmentManager()
			// .findFragmentById(R.id.map).getView();
			// if (mapView.getViewTreeObserver().isAlive()) {
			// mapView.getViewTreeObserver().addOnGlobalLayoutListener(
			// new ViewTreeObserver.OnGlobalLayoutListener() {
			// @SuppressLint("NewApi")
			// @SuppressWarnings("deprecation")
			// @Override
			// public void onGlobalLayout() {
			// LatLngBounds bounds = new LatLngBounds.Builder()
			// .include(orderPosition)
			// .include(currentPosition).build();
			// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
			// mapView.getViewTreeObserver()
			// .removeGlobalOnLayoutListener(
			// this);
			// } else {
			// mapView.getViewTreeObserver()
			// .removeOnGlobalLayoutListener(
			// this);
			// }
			// mMap.moveCamera(CameraUpdateFactory
			// .newLatLngBounds(bounds, 50));
			// }
			// });
			// }
			// }
			//
			// if (mTaskGetDirection != null) {
			// mTaskGetDirection.cancel(true);
			// mTaskGetDirection = null;
			// }
			// mTaskGetDirection = new GetDirection(currentPosition,
			// orderPosition);
			// mTaskGetDirection.execute();
		}

	}

	private class GetDirection extends
			AsyncTask<Void, Void, ArrayList<Pair<LatLng, LatLng>>> {
		private LatLng orgPosition, desPosition;

		public GetDirection(LatLng orgPosition, LatLng desPosition) {
			this.orgPosition = orgPosition;
			this.desPosition = desPosition;
		}

		@Override
		protected ArrayList<Pair<LatLng, LatLng>> doInBackground(Void... params) {
			String url = "https://maps.googleapis.com/maps/api/directions/json?sensor=true&origin="
					+ orgPosition.latitude
					+ ","
					+ orgPosition.longitude
					+ "&destination="
					+ desPosition.latitude
					+ ","
					+ desPosition.longitude;

			try {
				String respone = NetworkUtils.doRequest(url);
				ArrayList<Pair<LatLng, LatLng>> directions = new ArrayList<Pair<LatLng, LatLng>>();

				JSONObject result = new JSONObject(respone);
				JSONArray steps = result.getJSONArray("routes")
						.getJSONObject(0).getJSONArray("legs").getJSONObject(0)
						.getJSONArray("steps");
				for (int i = 0; i < steps.length(); i++) {
					JSONObject step = steps.getJSONObject(i);
					LatLng startLocation, endLocation;
					JSONObject startLocationJSONObjet = step
							.getJSONObject("start_location");
					startLocation = new LatLng(
							startLocationJSONObjet.getDouble("lat"),
							startLocationJSONObjet.getDouble("lng"));
					JSONObject endLocationJSONObjet = step
							.getJSONObject("start_location");
					endLocation = new LatLng(
							endLocationJSONObjet.getDouble("lat"),
							endLocationJSONObjet.getDouble("lng"));
					directions.add(new Pair<LatLng, LatLng>(startLocation,
							endLocation));

				}
				return directions;
			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(ArrayList<Pair<LatLng, LatLng>> result) {
			if (result != null) {
				PolylineOptions options = new PolylineOptions();
				for (Pair<LatLng, LatLng> step : result) {
					options.add(step.first).add(step.second);
				}
				mMutablePolyline = mMap.addPolyline(options.color(
						getResources().getColor(R.color.blue_color)).width(2));
			}
			super.onPostExecute(result);
		}
	}
}
